Skip to content

Publish to npm on tag push via trusted publishing (OIDC) - #1048

Merged
SuuBro merged 4 commits into
G-Research:masterfrom
dev-milos:ci/release-publish-workflow
Jul 27, 2026
Merged

Publish to npm on tag push via trusted publishing (OIDC)#1048
SuuBro merged 4 commits into
G-Research:masterfrom
dev-milos:ci/release-publish-workflow

Conversation

@dev-milos

@dev-milos dev-milos commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Objective

Move Bobbit to automated, secure npm releases and migrate the root package to @gresearch/bobbit.

Changes

  • .github/workflows/release-publish.yml — a pushed v* tag validates the package version, installs dependencies, and publishes through npm trusted publishing with provenance. Stable versions use latest; prereleases use next.
  • package.json / package-lock.json — rename the root package to @gresearch/bobbit, make the scoped package public, and add repository metadata required for provenance.
  • Release runbook — move root publishing to CI while keeping binary sub-package publishing manual; post-release verification and reporting target @gresearch/bobbit.

Scope: root package only. Binary sub-packages, version bumps, notes, signed tags, and GitHub Releases keep their existing flow. User-facing installation instructions can continue referencing bobbit during the migration period.

Activation sequence

@gresearch/bobbit is a new scoped package. After this PR merges:

  1. Manually bootstrap the first @gresearch/bobbit publication as the one-time exception to normal CI-only publishing.
  2. Configure its npm trusted-publisher binding for org G-Research, repo bobbit, workflow release-publish.yml.
  3. Push the next release tag only after bootstrap and OIDC configuration are complete.

The unscoped bobbit package remains available during the transition; this PR does not dual-publish both identities.

Validation

  • Focused release-skill unit test passes.
  • Full build and type-check pass after merging current master.
  • npm ci succeeds and reports zero vulnerabilities.
  • The real OIDC publish cannot be tested from a fork because the trusted-publisher binding is scoped to G-Research/bobbit.

🤖 Generated with Bobbit

@dev-milos
dev-milos marked this pull request as ready for review July 24, 2026 11:42
@dev-milos
dev-milos requested a review from SuuBro as a code owner July 24, 2026 11:42
@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

Introduces automated trusted npm publishing for the scoped root package.

  • Publishes @gresearch/bobbit through GitHub Actions when a matching v* tag is pushed.
  • Uses npm OIDC trusted publishing with provenance and selects next for prereleases.
  • Aligns package metadata, lockfile identity, release documentation, verification commands, and tests with the scoped package.

Confidence Score: 5/5

The PR appears safe to merge with no blocking failures remaining in the fixes relevant to the previous review threads.

The scoped package metadata, lockfile, release verification, and reporting targets are now consistent, and no blocking failure remains.

Important Files Changed

Filename Overview
.github/workflows/release-publish.yml Adds the tag-triggered OIDC workflow that validates the version and publishes the root package with the appropriate dist-tag.
package.json Migrates the root package identity to @gresearch/bobbit and adds publishing and repository metadata.
package-lock.json Synchronizes the lockfile root identity with the scoped package name.
.claude/skills/release/SKILL.md Updates the release procedure for CI-only root publishing and scoped-package verification and reporting.
docs/releasing.md Documents automated root publishing while retaining manual publication of binary sub-packages.
tests2/core/release-skill-preflight-order.test.ts Pins the scoped package identity across release installation, import, and reporting instructions.
tests2/tests-map.json Updates the registered test rationale to include scoped npm identity coverage.

Sequence Diagram

sequenceDiagram
    participant M as Maintainer
    participant GH as GitHub
    participant CI as release-publish.yml
    participant NPM as npm Registry
    M->>GH: "Push signed v<version> tag"
    GH->>CI: Trigger tag workflow
    CI->>CI: Verify tag matches package.json
    CI->>CI: npm ci and prepublishOnly build
    CI->>NPM: npm publish via OIDC with provenance
    NPM-->>CI: "Publish @gresearch/bobbit"
    CI-->>M: Workflow result
Loading

Reviews (3): Last reviewed commit: "Merge master into ci/release-publish-wor..." | Re-trigger Greptile

Comment thread package.json
Comment thread .github/workflows/release-publish.yml
Adds .github/workflows/release-publish.yml: on a v* tag push it builds and
publishes the root bobbit package to npm using trusted publishing (OIDC) with
automatic provenance -- no NPM_TOKEN, no OTP. Mirrors the validated
gr-oss-developers/trusted-publishing-demo workflow (top-level id-token: write,
Node 24 for npm >= 11.5.1, npm publish --provenance), plus the two things
bobbit needs that the demo doesn't: npm ci (bobbit has deps; the build runs via
the existing prepublishOnly hook) and a tag-vs-package.json-version guard.

package.json gains repository/homepage/bugs. repository is required for
provenance -- its URL must resolve to the building repo -- and was absent, which
is why the runbook's manual `npm publish --provenance` never actually produced
an attestation.

Runbook (SKILL.md + docs/releasing.md) now delegates the root publish to CI:
the human bumps the version, writes notes, signs the tag, and pushes it; the
tag push triggers the publish. npm login/OTP is scoped to the binary
sub-package republish case (still manual). Also fixes a stale SuuBro/bobbit
reference to G-Research/bobbit.

The root publish is not exercisable from a fork -- the npm trusted-publisher is
bound to the G-Research/bobbit repo identity. Validated here: actionlint clean,
npm publish --dry-run packs on Node 24, guard logic, and the JSON/YAML parse.
Manual prerequisites (npm admin, not code): configure the trusted publisher on
npmjs.com for bobbit -> G-Research/bobbit -> release-publish.yml. bobbit already
exists on npm (0.14.2), so no manual first publish is needed.
A v* tag with a semver pre-release suffix (v1.0.0-rc.1, v0.15.0-beta) now
publishes to the `next` dist-tag instead of `latest`, so a pre-release cannot
become the version `npm install bobbit` resolves. Stable tags still go to
`latest`.
Publish under the @gresearch npm org: sets name to @gresearch/bobbit and adds
publishConfig.access public (scoped packages default to restricted). Updates
the package-lock.json root name to match. The bin command stays `bobbit`.
This is a new scoped package on npm, so its first publish is a manual
bootstrap before trusted publishing takes over.
@dev-milos
dev-milos force-pushed the ci/release-publish-workflow branch from cbc0d21 to 15bf853 Compare July 27, 2026 08:49
Comment thread .claude/skills/release/SKILL.md Outdated
Co-authored-by: bobbit-ai <bobbit@bobbit.ai>
);
assert.doesNotMatch(skill, /npm install bobbit@/);
assert.doesNotMatch(skill, /import\('bobbit\//);
assert.doesNotMatch(skill, /npmjs\.com\/package\/bobbit\//);
@SuuBro
SuuBro merged commit 60aa0d4 into G-Research:master Jul 27, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants